package functions 
{	import functions.FunctionNode;	/**
	 * @author admin
	 */
	public class DynamicFunctionNode extends FunctionNode 
	{
		public var argnames:Array;
		private var functionbody:XML;
		private var _lexicalscope : Object;
		private var _myscope : Object;
		private static var instances : int = 1;
		
		public function DynamicFunctionNode()
		{
			funcname = "dynamicfunctionnode";	
			functiontype = FUNCTION;
		}
		
		public function init( args : XML, scope : Object )
		{
			argnames = new Array();
			// the args for lambda are two lists:
			// one containing the parameter names
			// and the next containing the functionbody.
			//	
			var arglist : XML = args.children()[0]; // supposed to receive <list>...</list>
			for each(var arg:XML in arglist.children())
			{
				trace("arg is " + arg);
				argnames.push( arg );
			}
			functionbody = args.children()[1].copy();
			_lexicalscope = scope;
			_myscope = new Object();
			_myscope["parentscope"] = _lexicalscope;
			_myscope["scopename"] = "dynamicfunctionscope" + (instances++);
			_myscope["toString"] = function() { return "Dynamic function scope";};
			
			// And here's where we bake in the values
			// that were present where we were instantiated.
			// or closures, if you will.
			
			for( var i:String in scope)
			{
				if ( i.indexOf("symbolvalue") > -1 )
				{
					_myscope[ i ] = scope[ i ];
				}
			}
		}
		
		override public function getValue( args : XML, scope : Object ) : XML
		{
			// ok, so we're getting arg values.
			// we need to assign them to the argnames we were given in our constructor.
			// so we make a new scope in which to define them.
			// we cycle through them
			// and assign each to the matching argname that was given us in our constructor.
			// then we use our newscope to evaluate the functionbody we were also given in our constructor.
			
			
			for (var i:int = 0; i < argnames.length; i++ )
			{
				_myscope[ "symbolvalue" + argnames [ i ] ] = args.children()[i];
			}
			
			

			
			return Evaluator.evaluate( functionbody, _myscope );
		}
		
		public function toString():String
		{
			return "This is a DynamicFunctionNode. ";
		}
		
				}}